package com.moyq5.mvc.maker.test.bean.entity;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.PrePersist;
import javax.persistence.Table;

import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.GenericGenerator;

import com.moyq5.mvc.maker.test.bean.custom.NotifyEntity;
import com.moyq5.mvc.maker.test.bean.enums.SysD0RateType;
import com.moyq5.mvc.maker.test.bean.enums.SysFeeHandle;
import com.moyq5.mvc.maker.test.bean.enums.SysLiquidateType;
import com.moyq5.mvc.maker.test.bean.enums.SysOwnerType;
import com.moyq5.mvc.maker.test.bean.enums.SysPayMethod;
import com.moyq5.mvc.maker.test.bean.enums.SysPayStatus;
import com.moyq5.mvc.maker.test.bean.enums.SysPayType;
import com.moyq5.mvc.maker.test.bean.enums.SysSettleStatus;
import com.moyq5.mvc.maker.test.bean.enums.SysSettleType;
import com.moyq5.mvc.maker.test.bean.enums.UserChargeType;

/**
 * 消费者支付记录
 * @author Moyq5
 * @date 2018年4月14日
 */
@Entity
@Table(name = "uc_user_order",indexes={@Index(columnList="add_time")})
@DynamicUpdate
public class UserOrder extends NotifyEntity implements java.io.Serializable {

	private static final long serialVersionUID = 1L;
	/**
	 * 订单ID
	 */
	@Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "native")@GenericGenerator(name = "native", strategy = "native")
    @Column(name = "order_id")
	private Long orderId;
	/**
	 * 订单号
	 */
	@Column(name = "order_no", nullable = false, length = 30, unique = true)
	private String orderNo;
	/**
	 * 消费者
	 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "user_id")
	private User user;
	/**
	 * 门店
	 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "shop_id")
	private Shop shop;
	/**
	 * 商家
	 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "merch_id", nullable = false)
	private Merch merch;
	/**
	 * 代理商
	 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "agent_id", nullable = false)
	private Agent agent;
	/**
	 * 归属类型
	 */
	@Enumerated(EnumType.ORDINAL)
	@Column(name = "owner_type", precision = 2, nullable = false)
	private SysOwnerType ownerType;
	/**
	 * 套餐
	 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "meal_id")
	private Meal meal;
	/**
	 * 商品名称（即套餐名称）
	 */
	@Column(name = "name", length = 200, nullable = false)
	private String name;
	/**
     * 订单金额
     */
    @Column(name = "amount", nullable = false, precision = 10, scale = 2)
    private BigDecimal amount;
    /**
     * 支付金额
     */
    @Column(name = "pay_amount", nullable = false, precision = 10, scale = 2)
    private BigDecimal payAmount;
    /**
     * 已退款金额
     */
    @Column(name = "refund_amount", nullable = false, precision = 10, scale = 2, columnDefinition = "decimal(10,2) default '0'")
    private BigDecimal refundAmount;
	/**
	 * (套餐)充值类型
	 */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "charge_type", columnDefinition="int(1) default '0'")
	private UserChargeType chargeType;
	/**
     * (套餐)充值数量（积分）
     */
    @Column(name = "quantity", nullable = false, precision = 10, scale = 0)
    private Integer quantity;
    /**
	 * 支付渠道
	 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "channel_id")
	private TraChannel channel;
	/**
	 * 渠道名称
	 */
	@Column(name = "channel_name", length = 60)
	private String channelName;
	/**
	 * 渠道商户
	 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "channel_merch_id")
	private TraChannelMerch channelMerch;
	/**
	 * 渠道商户号
	 */
	@Column(name = "channel_merch_no", length = 32)
	private String channelMerchNo;
	/**
	 * 渠道商户名称
	 */
	@Column(name = "channel_merch_name", length = 100)
	private String channelMerchName;
	/**
	 * 渠道订单号
	 */
	@Column(name = "channel_order_no", length = 60)
	private String channelOrderNo;
	/**
	 * 主扫时为用户付款码内容，被扫时为支付二维码内容
	 */
	@Column(name = "pay_url", length = 1000)
	private String payUrl;
	/**
	 * 支付类型
	 */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "pay_type", columnDefinition="int(1) default '0'")
	private SysPayType payType;
    /**
	 * 支付方式
	 */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "pay_method", precision = 2, nullable = false)
	private SysPayMethod payMethod;
    /**
	 * 结算类型
	 */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "settle_type", precision = 2, nullable = false)
	private SysSettleType settleType;
	/**
	 * 支付状态
	 */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "status", columnDefinition="int(1) default '0'")
	private SysPayStatus status;
    /**
	 * 支付状态描述
	 */
	@Column(name = "status_desc", length = 300)
	private String statusDesc;
	/**
	 * （后台管理员）强制支付状态
	 */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "force_status")
	private SysPayStatus forceStatus;
    
	/**
	 * 清算方类型
	 */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "liquidate_type", precision = 2)
	private SysLiquidateType liquidateType;
    /**
     * 手续费扣除方式
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "fee_handle", precision = 2)
	private SysFeeHandle feeHandle;
	/**
	 * D0费率类型
	 */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "d0_rate_type", precision = 2)
	private SysD0RateType d0RateType;
    /**
	 * 金钱交易记录
	 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "trade_id")
	private TraTrade trade;
	/**
	 * 付款人（名称）
	 */
	@Column(name = "payer", length = 100)
	private String payer;
	/**
	 * 支付账户
	 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "payer_account_id")
	private TraAccount payerAccount;
	/**
	 * 支付备注
	 */
	@Column(name = "payer_remark", length = 100)
	private String payerRemark;
	/**
	 * 付款人微信公众号支付时的OpenId
	 */
	@Column(name = "wx_open_id", length = 30)
	private String wxOpenId;
	/**
	 * APP支付时APP在微信开放平台上的APPId
	 */
	@Column(name = "wx_app_id", length = 30)
	private String wxAppId;
	/**
	 * （开放接口）支付后返回的页面地址
	 */
	@Column(name = "cus_return_url", length = 200)
	private String cusReturnUrl;
	/**
	 * 交易发起时间
	 */
	@Column(name = "order_time", nullable = false, columnDefinition="datetime")
	private Date orderTime;
	/**
	 * 支付完成时间
	 */
	@Column(name = "pay_time", columnDefinition="datetime")
	private Date payTime;
	/**
	 * 结算状态
	 */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "settle_status", nullable = false, columnDefinition="int(1) default '0'")
	private SysSettleStatus settleStatus;
    /**
	 * 结算时间
	 */
	@Column(name = "settle_time", columnDefinition="datetime")
	private Date settleTime;
	/**
	 * 手续费
	 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "cost_id")
	private TraCost cost;
	/**
	 * 个人码收款号
	 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "qrcode_account_id")
	private TraChannelQrcodeAccount qrcodeAccount;
	/**
	 * （支付）有效时间
	 */
	@Column(name = "expire_time", columnDefinition="datetime")
	private Date expireTime;
	/**
	 * 记录添加时间
	 */
	@Column(name = "add_time", nullable = false, columnDefinition="datetime")
	private Date addTime;
	
	@PrePersist
	public void prePersist() {
		super.prePersist();
		if (null == orderNo) {
			String merchNo = merch.getMerchNo();
			String prefix = merchNo.substring(merchNo.length() - 8, merchNo.length());
			prefix = String.valueOf(Long.parseLong(prefix));
			if (prefix.length() < 8) {
				prefix += (Math.round(Math.random()*(Math.pow(10, 8 - prefix.length()) - Math.pow(10, 8 - prefix.length() -1) - 1) + Math.pow(10, 8 - prefix.length())));
			}
			orderNo = prefix + Long.parseLong(new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()) + Math.round(Math.random()*(1e3-1e2-1) + 1e3));
			
		}
		if (null == payAmount) {
			payAmount = amount;
		}
		if (null == refundAmount) {
			refundAmount = BigDecimal.ZERO;
		}
		if (null == status) {
			status = SysPayStatus.NEW;
		}
		if (null == statusDesc) {
			statusDesc = status.getText();
		}
		if (null == orderTime) {
			orderTime = new Date();
		}
		if (null == settleStatus) {
			settleStatus = SysSettleStatus.UNSETTLED;
		}
		if (null == expireTime) {
			expireTime = new Date(System.currentTimeMillis() + 1200000);// 默认20分钟内订单有效
		}
		if (null == addTime) {
			addTime = new Date();
		}
	}

	public Long getOrderId() {
		return orderId;
	}

	public void setOrderId(Long orderId) {
		this.orderId = orderId;
	}

	public String getOrderNo() {
		return orderNo;
	}

	public void setOrderNo(String orderNo) {
		this.orderNo = orderNo;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public Shop getShop() {
		return shop;
	}

	public void setShop(Shop shop) {
		this.shop = shop;
	}

	public Merch getMerch() {
		return merch;
	}

	public void setMerch(Merch merch) {
		this.merch = merch;
	}

	public Agent getAgent() {
		return agent;
	}

	public void setAgent(Agent agent) {
		this.agent = agent;
	}

	public Meal getMeal() {
		return meal;
	}

	public void setMeal(Meal meal) {
		this.meal = meal;
	}

	public BigDecimal getPayAmount() {
		return payAmount;
	}

	public void setPayAmount(BigDecimal payAmount) {
		this.payAmount = payAmount;
	}

	public UserChargeType getChargeType() {
		return chargeType;
	}

	public void setChargeType(UserChargeType chargeType) {
		this.chargeType = chargeType;
	}

	public Integer getQuantity() {
		return quantity;
	}

	public void setQuantity(Integer quantity) {
		this.quantity = quantity;
	}

	public TraChannel getChannel() {
		return channel;
	}

	public void setChannel(TraChannel channel) {
		this.channel = channel;
	}

	public String getChannelName() {
		return channelName;
	}

	public void setChannelName(String channelName) {
		this.channelName = channelName;
	}

	public TraChannelMerch getChannelMerch() {
		return channelMerch;
	}

	public void setChannelMerch(TraChannelMerch channelMerch) {
		this.channelMerch = channelMerch;
	}

	public String getChannelMerchNo() {
		return channelMerchNo;
	}

	public void setChannelMerchNo(String channelMerchNo) {
		this.channelMerchNo = channelMerchNo;
	}

	public String getChannelMerchName() {
		return channelMerchName;
	}

	public void setChannelMerchName(String channelMerchName) {
		this.channelMerchName = channelMerchName;
	}

	public String getChannelOrderNo() {
		return channelOrderNo;
	}

	public void setChannelOrderNo(String channelOrderNo) {
		this.channelOrderNo = channelOrderNo;
	}

	public String getPayUrl() {
		return payUrl;
	}

	public void setPayUrl(String payUrl) {
		this.payUrl = payUrl;
	}

	public SysPayType getPayType() {
		return payType;
	}

	public void setPayType(SysPayType payType) {
		this.payType = payType;
	}

	public SysPayMethod getPayMethod() {
		return payMethod;
	}

	public void setPayMethod(SysPayMethod payMethod) {
		this.payMethod = payMethod;
	}

	public SysSettleType getSettleType() {
		return settleType;
	}

	public void setSettleType(SysSettleType settleType) {
		this.settleType = settleType;
	}

	public SysPayStatus getStatus() {
		return status;
	}

	public void setStatus(SysPayStatus status) {
		this.status = status;
	}

	public String getStatusDesc() {
		return statusDesc;
	}

	public void setStatusDesc(String statusDesc) {
		this.statusDesc = statusDesc;
	}

	public SysLiquidateType getLiquidateType() {
		return liquidateType;
	}

	public void setLiquidateType(SysLiquidateType liquidateType) {
		this.liquidateType = liquidateType;
	}

	@Deprecated
	public SysFeeHandle getFeeHandle() {
		return feeHandle;
	}

	@Deprecated
	public void setFeeHandle(SysFeeHandle feeHandle) {
		this.feeHandle = feeHandle;
	}

	public SysD0RateType getD0RateType() {
		return d0RateType;
	}

	public void setD0RateType(SysD0RateType d0RateType) {
		this.d0RateType = d0RateType;
	}

	public TraTrade getTrade() {
		return trade;
	}

	public void setTrade(TraTrade trade) {
		this.trade = trade;
	}

	public TraAccount getPayerAccount() {
		return payerAccount;
	}

	public void setPayerAccount(TraAccount payerAccount) {
		this.payerAccount = payerAccount;
	}

	public String getPayerRemark() {
		return payerRemark;
	}

	public void setPayerRemark(String payerRemark) {
		this.payerRemark = payerRemark;
	}

	public String getWxOpenId() {
		return wxOpenId;
	}

	public void setWxOpenId(String wxOpenId) {
		this.wxOpenId = wxOpenId;
	}

	public String getWxAppId() {
		return wxAppId;
	}

	public void setWxAppId(String wxAppId) {
		this.wxAppId = wxAppId;
	}

	public String getCusReturnUrl() {
		return cusReturnUrl;
	}

	public void setCusReturnUrl(String cusReturnUrl) {
		this.cusReturnUrl = cusReturnUrl;
	}

	public Date getAddTime() {
		return addTime;
	}

	public void setAddTime(Date addTime) {
		this.addTime = addTime;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public BigDecimal getRefundAmount() {
		return refundAmount;
	}

	public void setRefundAmount(BigDecimal refundAmount) {
		this.refundAmount = refundAmount;
	}

	public Date getOrderTime() {
		return orderTime;
	}

	public void setOrderTime(Date orderTime) {
		this.orderTime = orderTime;
	}

	public Date getPayTime() {
		return payTime;
	}

	public void setPayTime(Date payTime) {
		this.payTime = payTime;
	}

	public BigDecimal getAmount() {
		return amount;
	}

	public void setAmount(BigDecimal amount) {
		this.amount = amount;
	}

	public String getPayer() {
		return payer;
	}

	public void setPayer(String payer) {
		this.payer = payer;
	}

	public SysPayStatus getForceStatus() {
		return forceStatus;
	}

	public void setForceStatus(SysPayStatus forceStatus) {
		this.forceStatus = forceStatus;
	}

	public SysOwnerType getOwnerType() {
		return ownerType;
	}

	public void setOwnerType(SysOwnerType ownerType) {
		this.ownerType = ownerType;
	}

	public SysSettleStatus getSettleStatus() {
		return settleStatus;
	}

	public void setSettleStatus(SysSettleStatus settleStatus) {
		this.settleStatus = settleStatus;
	}

	public Date getSettleTime() {
		return settleTime;
	}

	public void setSettleTime(Date settleTime) {
		this.settleTime = settleTime;
	}

	public TraCost getCost() {
		return cost;
	}

	public void setCost(TraCost cost) {
		this.cost = cost;
	}

	public TraChannelQrcodeAccount getQrcodeAccount() {
		return qrcodeAccount;
	}

	public void setQrcodeAccount(TraChannelQrcodeAccount qrcodeAccount) {
		this.qrcodeAccount = qrcodeAccount;
	}

	public Date getExpireTime() {
		return expireTime;
	}

	public void setExpireTime(Date expireTime) {
		this.expireTime = expireTime;
	}
	
}
